#include "app_mqtt.h"
#include "log/log.h"
#include <MQTTClient.h>
#include <string.h>

//发送数据要用的初始化数据
static MQTTClient_message pubmsg = MQTTClient_message_initializer; //发送对象
//这俩原本是写在main函数里的，现在放在这里，因为我们只发一条
static MQTTClient client;  //客户端
static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; //连接选项
//定义回调函数变量，接受数据后调用
static int (*recv_callback)(char *json) = NULL;

//三个回调函数：
//客户端消息发布回调
void delivered(void *context, MQTTClient_deliveryToken dt)
{
    printf("消息发送完成\n");
}
 
//数据到达客户端回调
int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    int result = 0; //默认失败
    if(recv_callback!=NULL){
        result= recv_callback(message->payload)==0?1:0;  //调用回调函数，成功返回1，失败返回0
    }
    
    //释放内存
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    //发送成功返回1
    return result;
}
 
//连接断开回调
void connlost(void *context, char *cause)
{
    printf("连接断开，原因%s\n",cause);
}

//初始化MQTT客户端
int app_mqtt_init(void){
    //创建客户端
    if(MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)!=0){
        log_error("创建客户端失败\n");
        return -1;
    }
    //注册回调函数
    if(MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)!=0){
        log_error("注册回调函数失败\n");
        MQTTClient_destroy(&client);
        return -1;
    } 
    //连接客户端
    if(MQTTClient_connect(client, &conn_opts)!=0){
        log_error("连接客户端失败\n");
        MQTTClient_destroy(&client);
        return -1;
    }
    //订阅主题
    if(MQTTClient_subscribe(client, TOPIC_RTG, QOS)!=0){
        log_error("订阅主题失败\n");
        app_mqtt_close();
        return -1;
    }
    return 0;
}

//关闭MQTT客户端
void app_mqtt_close(void){
    MQTTClient_disconnect(client, TIMEOUT);
    MQTTClient_destroy(&client);
}

//发布消息到MQTT服务器
int app_mqtt_send(char *json){
    pubmsg.payload = json;
    pubmsg.payloadlen = strlen(json);
    pubmsg.qos = QOS;
    int result= MQTTClient_publishMessage(client, TOPIC_GTR, &pubmsg, NULL);
    if(result!=0){
        log_error("发送消息失败\n");
        return -1;
    }
    return 0;
}

//注册接收消息回调函数（当收到消息时调用）
//回调函数接收的也是json格式字符串,返回int表示接受成功与否
void app_mqtt_registRecvCallback(int (*callback)(char *json)){
    recv_callback = callback;
}

